class BCJ{
public:
    vector<int> parent;
    vector<int> size;
    int num;
    BCJ(int n):parent(n),size(n),num(0){
        for(int i = 0;i < n;i++){
            parent[i] = i;
        }
    }
    int find(int u){
        return u == parent[u] ? u : find(parent[u]);
    }
    bool isSet(int i,int j){
        int x = find(i);
        int y = find(j);
        if(parent[x] == parent[y]){
            return false;
        }
        if(size[x] < size[y]){
            swap(x,y);
        }
        parent[y] = x;
        size[x] += size[y];
        num++;
        return true;
    }
};

class Solution {
public:
    vector<vector<int>> findCriticalAndPseudoCriticalEdges(int n, vector<vector<int>>& edges) {
        int m = edges.size();
        for(int i = 0;i < m;i++){
            edges[i].push_back(i);
        }
        sort(edges.begin(),edges.end(),[](auto& a,auto& b){
            return a[2] < b[2];
        });
        
        BCJ bcj(n);
        int value = 0;
        for(int i = 0;i < m;i++){
            if(bcj.isSet(edges[i][0],edges[i][1])){
                value += edges[i][2];
            }
        }
        
        vector<vector<int> > ret(2);
        
        for(int i = 0;i < m;i++){
            BCJ bcj1(n);
            int v = 0;
            for(int j = 0;j < m;j++){
                if(i != j && bcj1.isSet(edges[j][0],edges[j][1])){
                    v += edges[j][2];
                }
            }
            
            if(bcj1.num == n - 1 && v > value || bcj1.num != n - 1){
                ret[0].push_back(edges[i][3]);
                continue;
            }
            
            BCJ bcj2(n);
            bcj2.isSet(edges[i][0],edges[i][1]);
            v = edges[i][2];
            for(int j = 0;j < m;j++){
                if(i != j && bcj2.isSet(edges[j][0],edges[j][1])){
                    v += edges[j][2];
                }
            }
            if( v == value){
                ret[1].push_back(edges[i][3]);
            }
        }
        return ret;
        
    }
};
